package com.fly.user.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.fly.common.common.ErrorConstant;
import com.fly.common.exception.BusinessException;
import com.fly.common.idworker.IdWorker;
import com.fly.common.model.OrderEntity;
import com.fly.common.model.UserEntity;
import com.fly.common.request.user.AddUserRequest;
import com.fly.common.request.user.QueryUserPageRequest;
import com.fly.common.request.user.UpdateUserRequest;
import com.fly.common.util.DozerBeanMapperUtil;
import com.fly.common.util.MD5Encoder;
import com.fly.common.vo.ResponseVO;
import com.fly.common.vo.order.UserOrderVO;
import com.fly.common.vo.user.JWT;
import com.fly.common.vo.user.UserVO;
import com.fly.user.service.PropagationService;
import com.fly.user.service.UserService;
import com.fly.user.client.OrderClient;
import com.fly.user.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private PropagationService propagationService;

    @Autowired
    private OrderClient orderClient;

    private final MD5Encoder encoder = new MD5Encoder();

    /**
     * 获取用户信息根据用户主键
     *
     * @param userId 用户主键
     * @return 用户信息
     */
    @Override
    public UserVO queryUserById(Long userId) {
        UserEntity userEntity = userMapper.selectById(userId);
        if (userEntity == null) {
            throw new BusinessException(ErrorConstant.USER_NULL_ERROR, ErrorConstant.USER_NULL_ERROR_MSG);
        }
        return DozerBeanMapperUtil.dozerBeanMapper(userEntity, UserVO.class);
    }

    /**
     * 获取用户列表
     *
     * @return 用户列表
     */
    @Override
    public List<UserVO> queryUserList() {
        List<UserEntity> userEntities = userMapper.selectList(null);
        return getUserVOS(userEntities);
    }

    /**
     * 分页获取用户信息
     *
     * @param request 分页请求对象
     * @return 用户信息
     */
    @Override
    public Page<UserVO> queryUserPage(QueryUserPageRequest request) {
        Page<UserVO> page = new Page<>(request.getCurrent(), request.getSize(), "user_id", true);
        List<UserEntity> userEntities = userMapper.selectPage(page, getQueryUserPageCondition(request));
        List<UserVO> userVOList = getUserVOS(userEntities);
        return page.setRecords(userVOList);
    }

    /**
     * 新增用户
     *
     * @param request 用户信息
     */
    @Override
    public void addUser(AddUserRequest request) {
        UserEntity userEntity = DozerBeanMapperUtil.dozerBeanMapper(request, UserEntity.class);
        userEntity.setUserId(idWorker.nextId());
        userMapper.insert(userEntity);
    }

    /**
     * 修改用户信息
     *
     * @param request 用户信息
     */
    @Override
    public ResponseVO updateUser(UpdateUserRequest request) {
        UserEntity userEntity = userMapper.selectById(request.getUserId());
        if (userEntity == null) {
            return new ResponseVO().setResult(ErrorConstant.USER_NULL_ERROR, ErrorConstant.USER_NULL_ERROR_MSG);
        }
        userEntity = DozerBeanMapperUtil.dozerBeanMapper(request, UserEntity.class);
        userMapper.updateById(userEntity);
        return new ResponseVO();
    }

    /**
     * 删除用户信息
     *
     * @param userId 用户主键
     */
    @Override
    public void deleteUser(Long userId) {
        userMapper.deleteById(userId);
    }

    /**
     * 测试批量数据操作，回滚
     *
     * @throws Exception 保存异常
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public void batchSaveUser() throws Exception {
        List<UserEntity> userList = new ArrayList<>();
        UserEntity u1 = new UserEntity();
        u1.setUserId(idWorker.nextId());
        UserEntity u2 = new UserEntity();
        u2.setUserId(idWorker.nextId());
        UserEntity u3 = new UserEntity();
        u3.setUserId(idWorker.nextId());
        userList.add(u1);
        userList.add(u2);
        userList.add(u3);
        propagationService.testPropagationA();
        propagationService.testPropagationB();
        for (int i = 0; i < userList.size(); i++) {
            userMapper.insert(userList.get(i));
            if (i == 1) {
                throw new RuntimeException("测试事务回滚");
            }
        }
    }

    /**
     * 获取用户数量
     *
     * @return 用户数量
     */
    @Override
    public Long queryUserCount() {
        return userMapper.queryUserCount();
    }

    /**
     * 根据主键获取用户信息
     *
     * @param userId 用户主键
     * @return 用户信息
     */
    @Override
    public UserVO findById(Long userId) {
        return userMapper.findById(userId);
    }

    /**
     * 注册
     *
     * @param request 用户信息
     */
    @Override
    public void register(AddUserRequest request) throws Exception {
        // 校验用户登录
        checkUserRegister(request);
        UserEntity userEntity = DozerBeanMapperUtil.dozerBeanMapper(request, UserEntity.class);
        userEntity.setPassword(encoder.encode(request.getPassword()));
        Integer total = userMapper.insert(userEntity);
        if (total != 1) {
            throw new BusinessException(ErrorConstant.USER_REGISTER_ERROR, ErrorConstant.USER_REGISTER_ERROR_MSG);
        }
    }

    /**
     * 校验用户登录
     *
     * @param request 账户、密码
     */
    private void checkUserRegister(AddUserRequest request) {
        // 判断用户名密码是否正确
        UserEntity userEntity = userMapper.findByUserName(request.getUserName());
        if (userEntity != null) {
            throw new BusinessException(ErrorConstant.USER_IS_HAD_ERROR, ErrorConstant.USER_IS_HAD_ERROR_MSG);
        }
    }

    /**
     * 获取我的订单
     *
     * @param userId 用户主键
     * @return 我的订单
     */
    @Override
    public List<UserOrderVO> queryMyOrder(Long userId) {
        List<UserOrderVO> myOrders = new ArrayList<>(16);
        ResponseVO<List<OrderEntity>> responseVO = orderClient.queryOrderByUserId(userId);
        if (responseVO.getResultCode() == ErrorConstant.SUCCESS) {
            List<OrderEntity> resultValue = responseVO.getResultValue();
            resultValue.forEach(orderEntity -> {
                UserOrderVO userOrderVO = DozerBeanMapperUtil.dozerBeanMapper(orderEntity, UserOrderVO.class);
                myOrders.add(userOrderVO);
            });
        }
        return myOrders;
    }

    /**
     * 获取分页对象列表响应对象
     *
     * @param userEntities 用户实体
     * @return 响应对象列表
     */
    private List<UserVO> getUserVOS(List<UserEntity> userEntities) {
        List<UserVO> userVOList = new ArrayList<>();
        userEntities.forEach(userEntity -> {
            UserVO userVO = DozerBeanMapperUtil.dozerBeanMapper(userEntity, UserVO.class);
            userVOList.add(userVO);
        });
        return userVOList;
    }


    /**
     * 获取分页查询用户信息条件对象
     *
     * @param request 请求对象
     * @return 条件对象
     */
    private EntityWrapper<UserEntity> getQueryUserPageCondition(QueryUserPageRequest request) {
        return getUserEntityEntityWrapper(request.getMobile(), request.getWorkNum(), request.getRealName());
    }

    /**
     * 拼接查询条件
     *
     * @param mobile   电话
     * @param workNum  工号
     * @param realName 姓名
     * @return 查询条件
     */
    private EntityWrapper<UserEntity> getUserEntityEntityWrapper(String mobile, String workNum, String realName) {
        EntityWrapper<UserEntity> queryUserCondition = new EntityWrapper<>();
        if (mobile != null && !"".equals(mobile)) {
            queryUserCondition.eq("mobile", mobile);
        }
        if (workNum != null && !"".equals(workNum)) {
            queryUserCondition.eq("work_num", workNum);
        }
        if (realName != null && !"".equals(realName)) {
            queryUserCondition.like("real_name", realName);
        }
        return queryUserCondition;
    }
}
